package com.sunda.spmsorder.service.impl;

import com.sunda.spmsorder.entity.MaterialApplication;
import com.sunda.spmsorder.entity.MaterialApplicationDtl;
import com.sunda.spmsorder.service.IFileOperationService;
import com.sunda.spmsorder.util.ExcelUtils;
import com.sunda.spmsuser.entity.SpmsUser;
import com.sunda.spmswms.entity.Werks;
import com.sunda.spmswms.entity.Workshop;
import com.sunda.spmswms.service.IWerksService;
import com.sunda.spmswms.service.IWorkshopService;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.errors.MinioException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFFormulaEvaluator;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;
import com.sunda.spmsuser.service.ISpmsUserService;

import java.awt.*;
import java.awt.Color;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Service
public class FileOperationServiceImpl implements IFileOperationService {
    @Autowired
    ISpmsUserService iSpmsUserService;
    @Autowired
    IWerksService iWerksService;
    @Autowired
    IWorkshopService iWorkshopService;

    @Override
    public String saveMaterialApplicationExcel(MaterialApplication materialApplication, List<MaterialApplicationDtl> materialApplicationDtlList, String filename) {
        List<Map<Integer, Object>> dataList = new ArrayList<>();
        if (materialApplicationDtlList.isEmpty()){
            return null;
        }
        // String filePath = ExcelUtils.class.getClassLoader().getResource("").getPath() + "exceltemplates/" + filename;
        String filePath = "ExcelCache/" + filename;
        File file = new File(filePath);
        // 获取用户信息
        SpmsUser spmsUser = iSpmsUserService.getByUserId(materialApplication.getUserId());
        // 获取工厂信息
        Werks werks = iWerksService.getWerkInfo(materialApplication.getWerks());
        // 获取车间信息
        Workshop workshop = iWorkshopService.getWorkshopInfo(materialApplication.getWerks(), materialApplication.getWorkshopCode());
        String worksshopNameZh = workshop == null ? materialApplication.getWorkshopCode() : workshop.getWorkshopNameZh();
        // 整理待导出数据
        for (MaterialApplicationDtl item : materialApplicationDtlList){
            Map<Integer, Object> dataMap = new HashMap<>();
            dataMap.put(0, werks.getWerksNameZh() + "-" + worksshopNameZh); // 来源：工厂中文+车间中文
            dataMap.put(1, "备品备件");
            dataMap.put(2, "所有工厂");
            dataMap.put(3, "=G4&\"_\"&H4");
            dataMap.put(4, item.getMaterialEnDesc() == null ? "" : item.getMaterialEnDesc());
            dataMap.put(5, item.getSpecs() == null ? "" : item.getSpecs());
            dataMap.put(6, item.getBasicUnit() == null ? "" : item.getBasicUnit().toUpperCase());
            dataMap.put(7, "");
            dataMap.put(8, "100");
            dataMap.put(9, "KG");
            dataMap.put(10, "CCM");
            dataMap.put(11, "L"); // 轻重货标识
            dataMap.put(12, "CN01");// 采购工厂
            dataMap.put(13, "R24");// MRP控制者
            dataMap.put(14, "F"); // 采购类型
            dataMap.put(15, spmsUser.getLastName() == null ? "" : spmsUser.getLastName());
            dataMap.put(16, item.getMaterialModel() == null ? "" : item.getMaterialModel());
            dataMap.put(17, item.getSupplierMaterialNo() == null ? "" : item.getSupplierMaterialNo());
            dataMap.put(18, item.getSupplyDesc() == null ? "" : item.getSupplyDesc());
            dataMap.put(19, item.getRelateEquipment() == null ? "" : item.getRelateEquipment());
//            dataMap.put(17, item.getEquipmentBrand() == null ? "" : item.getEquipmentBrand());
            dataMap.put(20, item.getEquipmentBrand() == null ? "" : item.getEquipmentBrand());
            dataMap.put(21, item.getEquipmentSpec() == null ? "" : item.getEquipmentSpec());
            dataMap.put(22, item.getEquipmentSupplier() == null ? "" : item.getEquipmentSupplier());
            dataMap.put(23, item.getThirdPartyPlatform() == null ? "" : item.getThirdPartyPlatform());
            dataMap.put(24, item.getLink() == null ? "" : item.getLink());
            dataMap.put(25, item.getSku() == null ? "" : item.getSku());
            dataList.add(dataMap);
        }
        // 使用ClassLoader加载properties配置文件生成对应的输入流
        InputStream in = ExcelUtils.class.getClassLoader().getResourceAsStream("exceltemplates/MaterialApplicationTemplate.xlsx");
        FileOutputStream fos = null;
        try {
            final XSSFWorkbook tpWorkbook = new XSSFWorkbook(in);
            // 新建一个Excel的工作空间
            Workbook workbook = new SXSSFWorkbook(100);
            // 把模板复制到新建的Excel
            workbook = tpWorkbook;
            // 填充数据，生成Excel
            fillExcelSheetDataMaterailApplication(dataList, workbook, "需填写", dataList.get(0).size());
            // 输出到服务器本地
            if (file.getParentFile().exists()){
                file.delete();
            }
            file.getParentFile().mkdir();
            file.createNewFile();
            fos = new FileOutputStream(file);
            workbook.write(fos);
        } catch (final IOException e) {
            e.printStackTrace();
        } catch (final IllegalArgumentException e) {
            e.printStackTrace();
        } catch (final Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != fos){
                    fos.flush();
                    fos.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return file.getAbsolutePath();
    }

    @Override
    public String saveMaterialApplicationPic(MultipartFile multipartFile, String filename) {
        String filePath = "PicCache/" + filename;
        File file = new File(filePath);
        FileOutputStream fos = null;
        InputStream stream = null;
        try {
            // 输出到服务器本地
            if (file.getParentFile().exists()){
                file.delete();
            }
            file.getParentFile().mkdir();
            file.createNewFile();
            fos = new FileOutputStream(file);
            stream = multipartFile.getInputStream();
            //写入目标文件
            byte[] buffer = new byte[1024*1024];
            int byteRead;
            try {
                while((byteRead=stream.read(buffer))!=-1){
                    fos.write(buffer, 0, byteRead);
                    fos.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (final IOException e) {
            e.printStackTrace();
        } catch (final IllegalArgumentException e) {
            e.printStackTrace();
        } catch (final Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != fos){
                    fos.close();
                }
                if (null != stream){
                    stream.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return file.getAbsolutePath();
    }

    @Override
    public String fileUploader(String filename, String localFilePath) {
        String fileUrl = "";
        try {
            // Minio文件服务器参数为：IP，账号，密码
            MinioClient minioClient = new MinioClient("http://192.168.106.89:9000", "minioadmin", "minioadmin");
            String bucketName = "spms";
            // 检查文件夹是否已经存在
            boolean isExist = minioClient.bucketExists(bucketName);
            if(isExist) {
                System.out.println("文件夹已经存在了");
            }
            else {
                // 创建一个名为managertest的文件夹
                System.out.println("文件夹还没存在");
                minioClient.makeBucket(bucketName);
            }
            // 使用putObject上传一个文件到文件夹中。
            //参数为：文件夹，要存成的名字，要存的文件
            minioClient.putObject(bucketName, filename, localFilePath);
            System.out.println("成功了");

            //使用getObject获取一个文件
            // 调用statObject()来判断对象是否存在。
            ObjectStat objectStat = minioClient.statObject(bucketName, filename);
            // 获取1.png的流并保存到photo.png文件中。
            // 参数为：文件夹，要获得的文件，要写入的文件
            fileUrl = minioClient.getObjectUrl(bucketName, filename);
            System.out.println("文件上传路径:" + fileUrl);
        }catch(MinioException e) {
            System.out.println("错误: " + e);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileUrl;
    }

    private void fillExcelSheetDataMaterailApplication(List<Map<Integer, Object>> dataList,Workbook wb,String sheetName, int lineLen){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd");  //日期格式化
        Sheet sheet = wb.getSheetAt(0);
        // 单元格样式
        XSSFCellStyle cellStyle = (XSSFCellStyle) wb.createCellStyle();
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        XSSFColor color = new XSSFColor(new Color(255,255,0), new DefaultIndexedColorMap()); //accepts a short value
        cellStyle.setFillForegroundColor(color.getIndexed());
        // TODO: 每行数据对应的列位置
        Map<Integer, Integer> colIndex = new HashMap<>();
        colIndex.put(0, 0);
        colIndex.put(1, 1);
        colIndex.put(2, 2);
        colIndex.put(3, 5);
        colIndex.put(4, 6);
        colIndex.put(5, 7);
        colIndex.put(6, 16);
        colIndex.put(7, 17);
        colIndex.put(8, 19);
        colIndex.put(9, 28);
        colIndex.put(10, 30);
        colIndex.put(11, 35);
        colIndex.put(12, 41);
        colIndex.put(13, 42);
        colIndex.put(14, 50);
        colIndex.put(15, 64);
        colIndex.put(16, 65);
        colIndex.put(17, 66);
        colIndex.put(18, 67);
        colIndex.put(19, 68);
//        colIndex.put(17, 69);
        colIndex.put(20, 69);
        colIndex.put(21, 70);
        colIndex.put(22, 71);
        colIndex.put(23, 72);
        colIndex.put(24, 73);
        colIndex.put(25, 74);
        //TODO：从第n行开始塞入真正的数据列表
        int rowIndex=3;
        Row row;
        Object obj;
        for(Map<Integer, Object> rowMap:dataList){
            try {
                row=sheet.getRow(rowIndex);
                if (row == null){
                    row=sheet.createRow(rowIndex);
                }
                rowIndex++;
                for(int i=0;i< lineLen;i++){
                    obj=rowMap.get(i);
                    if (obj==null) {
                        row.getCell(colIndex.get(i)).setCellValue("");
                    }else if (obj instanceof Date) {
                        String tempDate=simpleDateFormat.format((Date)obj);
                        row.getCell(colIndex.get(i)).setCellValue((tempDate==null)?"":tempDate);
                    }else {
                        if (row.getCell(colIndex.get(i)) == null) {
                            row.createCell(colIndex.get(i)).setCellValue(String.valueOf(obj));
                        }else{
                            row.getCell(colIndex.get(i)).setCellValue(String.valueOf(obj));
                        }
                    }
                    // 设置公式
                    if (i == 3){
//                        row.getCell(colIndex.get(i)).setCellType(CellType.FORMULA);
//                        row.getCell(colIndex.get(i)).setCellFormula(String.valueOf(obj));
//                        eval.evaluateFormulaCell(row.getCell(colIndex.get(i)));
                    }
                    // row.getCell(colIndex.get(i)).setCellStyle(cellStyle);
                }
            } catch (Exception e) {
                System.out.println("excel sheet填充数据 发生异常： " + e.fillInStackTrace());
            }
        }
    }
}
